package com.windystory.wslibrary.util;

import android.annotation.SuppressLint;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateTimeUtil {

    /**
     * 缺省的日期显示格式： yyyy-MM-dd
     */
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    /**
     * 缺省的日期时间显示格式：yyyy-MM-dd HH:mm:ss
     */
    public static final String DEFAULT_DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static final String[] NUMBERS = {"〇", "一", "二", "三", "四", "五", "六",
            "七", "八", "九"};

    /**
     * 私有构造方法，禁止对该类进行实例化
     */
    public DateTimeUtil() {
    }

    /**
     * 得到系统当前日期时间
     *
     * @return 当前日期时间
     */
    public static Date getNow() {
        return Calendar.getInstance().getTime();
    }

    /**
     * 得到用缺省方式格式化的当前日期
     *
     * @return 当前日期
     */
    public static String getDate() {
        return getDateTime(DEFAULT_DATE_FORMAT);
    }

    /**
     * 得到用缺省方式格式化的当前日期及时间
     *
     * @return 当前日期及时间
     */
    public static String getDateTime() {
        return getDateTime(DEFAULT_DATETIME_FORMAT);
    }

    /**
     * 得到系统当前日期及时间，并用指定的方式格式化
     *
     * @param pattern 显示格式
     * @return 当前日期及时间
     */
    public static String getDateTime(String pattern) {
        Date datetime = Calendar.getInstance().getTime();
        return getDateTime(datetime, pattern);
    }

    /**
     * 得到用指定方式格式化的日期
     *
     * @param date    需要进行格式化的日期
     * @param pattern 显示格式
     * @return 日期时间字符串
     */
    public static String getDateTime(Date date, String pattern) {
        if (null == pattern || "".equals(pattern)) {
            pattern = DEFAULT_DATETIME_FORMAT;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(date);
    }

    /**
     * 得到用指定方式格式化的日期
     *
     * @param date    需要进行格式化的日期
     * @param pattern 显示格式
     * @return 日期时间字符串
     */
    public static String getDate(String date, String pattern) {
        if (null == pattern || "".equals(pattern)) {
            pattern = DEFAULT_DATETIME_FORMAT;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
        return dateFormat.format(date);
    }


    /**
     * 得到用指定方式格式化的日期
     *
     * @param date 需要进行格式化的日期
     * @return 日期时间字符串
     */
    public static String getDateTime(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATETIME_FORMAT);
        return dateFormat.format(date);
    }

    /**
     * 得到用指定方式格式化的日期
     *
     * @param date 需要进行格式化的日期
     * @return 日期时间字符串
     */
    public static String getDate(Date date) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        return dateFormat.format(date);
    }

    /**
     * 得到当前年份
     *
     * @return 当前年份
     */
    public static int getCurrentYear() {
        return Calendar.getInstance().get(Calendar.YEAR);
    }

    /**
     * 得到当前月份
     *
     * @return 当前月份
     */
    public static int getCurrentMonth() {
        // 用get得到的月份数比实际的小1，需要加上
        return Calendar.getInstance().get(Calendar.MONTH) + 1;
    }

    /**
     * 得到当前日
     *
     * @return 当前日
     */
    public static int getCurrentDay() {
        return Calendar.getInstance().get(Calendar.DATE);
    }

    /**
     * 取得当前日期以后若干天的日期。如果要得到以前的日期，参数用负数。 例如要得到上星期同一天的日期，参数则为-7
     *
     * @param days 增加的日期数
     * @return 增加以后的日期
     */
    public static Date addDays(int days) {
        return add(getNow(), days, Calendar.DATE);
    }

    /**
     * 取得指定日期以后若干天的日期。如果要得到以前的日期，参数用负数。
     *
     * @param date 基准日期
     * @param days 增加的日期数
     * @return 增加以后的日期
     */
    public static Date addDays(Date date, int days) {
        return add(date, days, Calendar.DATE);
    }

    /**
     * 取得当前日期以后某月的日期。如果要得到以前月份的日期，参数用负数。
     *
     * @param months 增加的月份数
     * @return 增加以后的日期
     */
    public static Date addMonths(int months) {
        return add(getNow(), months, Calendar.MONTH);
    }

    /**
     * 取得指定日期以后某月的日期。如果要得到以前月份的日期，参数用负数。 注意，可能不是同一日子，例如2003-1-31加上一个月是2003-2-28
     *
     * @param date   基准日期
     * @param months 增加的月份数
     * @return 增加以后的日期
     */
    public static Date addMonths(Date date, int months) {
        return add(date, months, Calendar.MONTH);
    }

    /**
     * 内部方法。为指定日期增加相应的天数或月数
     *
     * @param date   基准日期
     * @param amount 增加的数量
     * @param field  增加的单位，年，月或者日
     * @return 增加以后的日期
     */
    private static Date add(Date date, int amount, int field) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    /**
     * 计算两个日期相差天数。 用第一个日期减去第二个。如果前一个日期小于后一个日期，则返回负数
     *
     * @param one 第一个日期数，作为比较
     * @param two 第二个日期数，作为基准
     * @return 两个日期相差天数
     */
    public static long diffDays(Date one, Date two) {
        return (one.getTime() - two.getTime()) / (24 * 60 * 60 * 1000);
    }

    /**
     * 计算两个日期相差天数数 如果前一个日期小于后一个日期，则返回负数
     *
     * @param one 第一个日期数，作为基准
     * @param two 第二个日期数，作为比较
     * @return 两个日期相差月份数
     */
    public static int diffday(Date one, Date two) {
        Calendar calendar = Calendar.getInstance();
        // 得到第一个日期的年分和月份数
        calendar.setTime(one);
        int dayOne = calendar.get(Calendar.DAY_OF_YEAR);
        // 得到第二个日期的年份和月份
        calendar.setTime(two);
        int dayTwo = calendar.get(Calendar.DAY_OF_YEAR);
        return dayOne - dayTwo;
    }

    /**
     * 计算两个日期相差月份数 如果前一个日期小于后一个日期，则返回负数
     *
     * @param one 第一个日期数，作为基准
     * @param two 第二个日期数，作为比较
     * @return 两个日期相差月份数
     */
    public static int diffMonths(Date one, Date two) {
        Calendar calendar = Calendar.getInstance();
        // 得到第一个日期的年分和月份数
        calendar.setTime(one);
        int yearOne = calendar.get(Calendar.YEAR);
        @SuppressLint("WrongConstant") int monthOne = calendar.get(Calendar.MONDAY);
        // 得到第二个日期的年份和月份
        calendar.setTime(two);
        int yearTwo = calendar.get(Calendar.YEAR);
        @SuppressLint("WrongConstant") int monthTwo = calendar.get(Calendar.MONDAY);
        return (yearOne - yearTwo) * 12 + (monthOne - monthTwo);
    }

    /**
     * 计算两个日期相差天数。 用第一个日期减去第二个。如果前一个日期小于后一个日期，则返回负数
     *
     * @param beginTime 第一个日期数，作为基准
     * @param endTime   第二个日期数，作为比较
     * @return 两个日期相差天数
     */
    public static long diffSecond(String beginTime, String endTime) throws ParseException {
        SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date begin = dfs.parse(beginTime);
        Date end = dfs.parse(endTime);
        long between = (end.getTime() - begin.getTime()) / 1000;// 除以1000是为了转换成秒

        //long minute1 = between % 3600 / 60;
        //long second1 = between % 60 / 60;
        return between;
    }

    /**
     * 将一个字符串用给定的格式转换为日期类型。<br>
     * 注意：如果返回null，则表示解析失败
     *
     * @param datestr 需要解析的日期字符串
     * @param pattern 日期字符串的格式，默认为“yyyy-MM-dd”的形式
     * @return 解析后的日期
     */
    public static Date parse(String datestr, String pattern) {
        Date date = null;
        if (null == pattern || "".equals(pattern)) {
            pattern = DEFAULT_DATE_FORMAT;
        }
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);
            date = dateFormat.parse(datestr);
        } catch (ParseException e) {
        }
        return date;
    }

    /**
     * 返回本月的最后一天
     *
     * @return 本月最后一天的日期
     */
    public static Date getMonthLastDay() {
        return getMonthLastDay(getNow());
    }

    /**
     * 返回给定日期中的月份中的最后一天
     *
     * @param date 基准日期
     * @return 该月最后一天的日期
     */
    public static Date getMonthLastDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 将日期设置为下一月第一天
        calendar.set(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + 1, 1);
        // 减去1天，得到的即本月的最后一天
        calendar.add(Calendar.DATE, -1);
        return calendar.getTime();
    }

    /**
     * 返回给定日期中的返回大写年月日
     *
     * @param samRq 小写的年月日
     * @return 大写年月日
     */
    public static String rQ2CNRQ(String samRq) {
        String tmp = "";
        StringBuffer sb = new StringBuffer();
        // 转换年
        for (int i = 0; i < 4; i++) {
            tmp = samRq.substring(i, i + 1);
            sb.append(NUMBERS[Integer.parseInt(tmp)]);
        }
        sb.append("年");
        // 转换月
        tmp = samRq.substring(5, 6);
        // sb.append(NUMBERS[Integer.parseInt(tmp)]);
        if (!"0".equals(tmp)) {
            sb.append("十");
        }
        tmp = samRq.substring(6, 7);
        if (!"0".equals(tmp)) {
            sb.append(NUMBERS[Integer.parseInt(tmp)]);
        }
        sb.append("月");
        // 转换日
        tmp = samRq.substring(8, 9);
        if ("2".equals(tmp) || "3".equals(tmp)) {
            sb.append(NUMBERS[Integer.parseInt(tmp)]);
        }
        if (!"0".equals(tmp)) {
            sb.append("十");
        }
        tmp = samRq.substring(9, 10);
        if (!"0".equals(tmp)) {
            sb.append(NUMBERS[Integer.parseInt(tmp)]);
        }
        sb.append("日");

        return sb.toString();

    }

    /**
     * @param date 开始时间
     * @param
     * @return
     * @throws ParseException
     */
    public static String addMins(String date, String addMinutes) {
        String tmp = "";
        SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1;
        try {
            d1 = sim.parse(date);
            long time = d1.getTime();
            Long tm = Long.parseLong(addMinutes) * 60 * 1000;
            time += tm;
            Date d2 = new Date(time);
            tmp = getDateTime(d2, "yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return tmp;
    }

    public static final Long getSJC() {
        return System.currentTimeMillis();
    }


    /**
     * 本月第一天
     * <p>
     * zxl
     * 2017年5月17日 上午9:15:54
     * void
     */
    public static Date getMonthFirstDay() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        // 减去1天，得到的即本月的最后一天
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }


    /**
     * 获得年月yyyy-MM
     */
    public static String geYearMonth(Date date) {
        // TODO Auto-generated method stub
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        return sdf.format(date);
    }

    /**
     * 获取这个月所有的天列表
     *
     * @param month
     * @return
     * @throws ParseException
     */
    public static List<String> getDayList(String month) throws ParseException {
        // TODO Auto-generated method stub
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        Date monthDate = sdf.parse(month);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(monthDate);

        calendar.add(Calendar.MONTH, +1);
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        List<String> dayList = new ArrayList<String>();
        for (int i = 1; i <= day; i++) {
            if (i < 10) {
                dayList.add(month + "-0" + i);
            } else {
                dayList.add(month + "-" + i);
            }
        }

        return dayList;
    }

    /**
     * @param begin
     * @param end
     * @return
     * @throws ParseException
     */
    public static List<String> getBetween2Date(String begin, String end) throws ParseException {
        List<String> leaveList = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = sdf.parse(begin);
        Date endDate = sdf.parse(end);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        int endNum = calendar.get(Calendar.DAY_OF_YEAR);
        calendar.setTime(beginDate);
        int beginNum = calendar.get(Calendar.DAY_OF_YEAR);

        for (int i = 0; i <= endNum - beginNum; i++) {
            calendar.setTime(beginDate);
            calendar.add(Calendar.DAY_OF_YEAR, i);
            leaveList.add(sdf.format(calendar.getTime()));
        }
        return leaveList;
    }

    /**
     * zxl
     * 2017年8月28日 下午3:54:22
     *
     * @param begin
     * @param end
     * @return
     * @throws ParseException List<String>
     */
    public static int getBetweenDateNum(String begin, String end) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = sdf.parse(begin);
        Date endDate = sdf.parse(end);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        int endNum = calendar.get(Calendar.DAY_OF_YEAR);
        calendar.setTime(beginDate);
        int beginNum = calendar.get(Calendar.DAY_OF_YEAR);

        return endNum - beginNum;
    }

    /**
     * 获取两个时间之间的天数
     * <p>
     * zxl
     * 2017年6月30日 下午2:28:37
     *
     * @param startTime
     * @param endTime
     * @return List<String>
     * @throws ParseException
     */
    public static List<String> getDayList(String startTime, String endTime) throws ParseException {
        List<String> list = new ArrayList<String>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = sdf.parse(startTime);
        Date endDate = sdf.parse(endTime);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(endDate);
        int endNum = calendar.get(Calendar.DAY_OF_YEAR);
        calendar.setTime(beginDate);
        int beginNum = calendar.get(Calendar.DAY_OF_YEAR);

        for (int i = 0; i <= endNum - beginNum; i++) {
            calendar.setTime(beginDate);
            calendar.add(Calendar.DAY_OF_YEAR, i);
            list.add(sdf2.format(calendar.getTime()));
        }
        return list;
    }

    public static void main(String[] args) throws ParseException {
        System.out.println(getDayList("2017-12-01 00:00:00", "2018-01-01 00:00:00"));
    }

    /**
     * zxl
     * 2017年8月28日 下午4:01:24
     *
     * @param sickLeaveDate
     * @return Object
     */
    public static Date getDayAgo(Date sickLeaveDate, int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(sickLeaveDate);
        calendar.add(Calendar.DAY_OF_YEAR, num);
        return calendar.getTime();
    }

    /**
     * 之前的时间
     * <p>
     * zxl
     * 2017年9月21日 下午3:36:43
     *
     * @param date
     * @return long
     */
    public static long getHelfHourTime(Date date, int min) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - min);
        return calendar.getTimeInMillis();
    }

    /**
     * 判断当前时间与要比较的时间的大小
     *
     * @param time 比较时间
     * @return 1 当前时间大    0 当前时间小    -1 相等
     */
    public static int compareTime(String time) throws ParseException {
//		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//		java.util.Date now = df.parse("2004-03-26 13:31:40");
//		java.util.Date date=df.parse("2004-01-02 11:30:24");
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
        Date date = df.parse(time);
        Date currentTime = df.parse(getDateTime("HH:mm"));
        if (currentTime.compareTo(date) == 0) {
            return -1;
        } else if (currentTime.compareTo(date) < 0) {//当前时间小于比较时间
            return 0;
        } else {//当前时间大于比较时间
            return 1;
        }
    }


    /**
     * 比较时间
     *
     * @throws ParseException
     */
    public static boolean compareTime(String start, String end,String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);

        try {
            Date d1 = sdf.parse(start);
            Date d2 = sdf.parse(end);

            if (d1.before(d2) || d1.equals(d2)) {
                return true;
            } else {
                return false;
            }
        } catch (Exception e) {
            return false;
        }

    }

    /**
     * 比较时间
     *
     * @throws ParseException
     */
    public static boolean compareTime(String start, String end) {
        return compareTime(start, end,"yyyy-MM-dd HH:mm");
    }


    /**
     * 人性化时间显示  yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String timeRead4Man(String time) {
        if (time == null)
            return "";
        //今天时间 2019-06-03 15:48:52
        String todayTime = getDateTime();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {
            Date today = sdf.parse(todayTime);
            Date getTime = sdf.parse(time);

            String getTimeTemp = ((getTime.getYear() + 1900) + "-" + ((1 + getTime.getMonth()) > 9 ? (1 + getTime.getMonth()) : "0" + (1 + getTime.getMonth())) + "-" + getTime.getDate());
            String todayTemp = ((today.getYear() + 1900) + "-" + ((1 + today.getMonth()) > 9 ? (1 + today.getMonth()) : "0" + (1 + today.getMonth())) + "-" + (today.getDate()>9?today.getDate():"0"+today.getDate()));

            if (todayTemp.equals(getTimeTemp)) {
                //判断上下午
                int h = getTime.getHours();
                if (h < 12) {
                    return "上午" + (getTime.getHours() > 9 ? getTime.getHours() : "0" + (getTime.getHours())) + ":" + (getTime.getMinutes() > 9 ? getTime.getMinutes() : "0" + (getTime.getMinutes()));
                } else if (h == 12) {
                    return "中午" + (getTime.getHours() > 9 ? getTime.getHours() : "0" + (getTime.getHours())) + ":" + (getTime.getMinutes() > 9 ? getTime.getMinutes() : "0" + (getTime.getMinutes()));
                } else {
                    return "下午" + (getTime.getHours() > 9 ? getTime.getHours() : "0" + (getTime.getHours())) + ":" + (getTime.getMinutes() > 9 ? getTime.getMinutes() : "0" + (getTime.getMinutes()));
                }
            }else{
                //判断是不是昨天
                long diff = today.getTime() - getTime.getTime();
                long days = diff / (1000 * 60 * 60 * 24);
                if (days == 0){
                    return "昨天" + (getTime.getHours() > 9 ? getTime.getHours() : "0" + (getTime.getHours())) + ":" + (getTime.getMinutes() > 9 ? getTime.getMinutes() : "0" + (getTime.getMinutes()));
                }else{
                    return ((getTime.getYear() + 1900) + "/" + ((1 + getTime.getMonth()) > 9 ? (1 + getTime.getMonth()) : "0" + (1 + getTime.getMonth())) + "/" + (getTime.getDate()>9?getTime.getDate():"0"+getTime.getDate()));
                }
            }

        } catch (ParseException e) {
            return time;
        }

    }

}
